## [Функции анализа и подстановки строк](http://rus-linux.net/nlib.php?name=/MyLDP/algol/gnu_make/gnu_make_3-79_russian_manual.html#SEC77)

Ниже перечислены функции, оперирующие со строками:

$(subst заменяемый_фрагмент,замена,текст)
Производит текстовую замену в тексте текст: каждой вхождение подстроки заменяемый_фрагмент заменяется на фрагмент замена. Результат подставляется в место вызова функции. Результатом следующего примера:
$(subst ee,EE,feet on the street)
будет строка `fEEt on the strEEt'.
$(patsubst шаблон,замена,текст)
Находит в тексте разделенные пробелом слова, удовлетворяющие шаблону и заменяет их на строку замена. Шаблон может содержать символ `%', который работает как специальный шаблонный символ, соответствующий любому количеству произвольных символов внутри слова. Если строка замена также содержит символ `%', он будет заменен текстом, соответствующим символу `%' в шаблоне. Специальное значение символа `%' может быть отменено предшествующим ему символом `\'. Специальное значение символа `\', который мог бы отменить специальное значение символа `%', может, в свою очередь, быть отменено дополнительным символом `\'. Символы `\', отменяющие специальное значение символов `%' и `\', удаляются из шаблона перед тем, как он будет использоваться для сравнения или подстановки. Символы `\', не могущие повлиять на трактовку `%', остаются нетронутыми. Например, в шаблоне `the\%weird\\%pattern\\' за строкой `the%weird\' следует шаблонный символ `%' и строка `pattern\\'. Два завершающих символа `\' остаются нетронутыми, поскольку они не могут повлиять на трактовку символа `%'. Пробельные символы между словами преобразуются в одиночные пробелы; начальные и конечные пробелы отбрасываются. Например, результатом выражения
$(patsubst %.c,%.o,x.c.c bar.c)
будет строка `x.c.o bar.o'. Ссылка с заменой (смотрите раздел Ссылка с заменой) является упрощенным способом получения эффекта, аналогичного использованию функции patsubst. Выражение:
$(переменная:шаблон=замена)
эквивалентно
$(patsubst шаблон,замена,$(переменная))
Еще одна упрощенная форма записи имеется для распространенного способа использования функции patsubst: замены суффиксов в именах файлов. Выражение:
$(переменная:суффикс=замена)
эквивалентно:
$(patsubst %суффикс,%замена,$(переменная))
Пусть, например, у вас имеется список объектных файлов:
objects = foo.o bar.o baz.o
Тогда, для получения списка соответствующих исходных файлов, вы можете просто написать:
$(objects:.o=.c)
вместо того, чтобы использовать "обобщенную" форму записи:
$(patsubst %.o,%.c,$(objects))
$(strip строка)
Удаляет начальные и конечные пробелы из строки, а также заменяет все внутренние последовательности пробельных символов на одиночные пробелы. Так, результатом выражения `$(strip a b c )' будет строка `a b c'. Функция strip весьма полезна в условных конструкциях. Например, при использовании директив ifeq и ifneq для сравнения с пустой строкой `', обычно желательно, чтобы строка, целиком состоящая из пробельных символов, рассматривалась как пустая (смотрите раздел Условные части make-файла). Так, например, следующий фрагмент make-файла не всегда будет работать желаемым образом:
.PHONY: all
ifneq   "$(needs_made)" ""
all: $(needs_made)
else
all:;@echo 'Nothing to make!'
endif
Заменив в директиве ifneq ссылку на переменную `$(needs_made)' вызовом функции `$(strip $(needs_made))', мы получим более надежно работающую конструкцию.
$(findstring фрагмент,строка)
Производит поиск фрагмента в строке. В случае успеха (фрагмент найден) возвращает значение фрагмент; в противном случае, возвращается пустая строка. Эту функцию можно использовать в условных конструкциях для проверки наличия в рассматриваемой строке определенной подстроки. Результатами следующих двух примеров:
$(findstring a,a b c)
$(findstring a,b c)
будут, соответственно, строки `a' и `' (пустая строка). В разделе Проверка опций запуска make в условных конструкциях приведен достаточно реалистичный пример использования функции findstring.
$(filter шаблон...,текст)
Удаляет из текста все разделенные пробелами слова, которые не удовлетворяют ни одному из указанных шаблонов и возвращает только слова, подходящие под шаблоны. Шаблоны записываются с использованием шаблонного символа `%', аналогично тому, как это делается в функции patsubst (описана выше). Функция filter может быть использована для отделения друг от друга строк (например, имен файлов) разных "типов". В следующем примере:
sources := foo.c bar.c baz.s ugh.h
foo: $(sources)
        cc $(filter %.c %.s,$(sources)) -o foo
объявляется, что цель `foo' зависит от файлов `foo.c', `bar.c', `baz.s' и `ugh.h', однако, при вызове компилятора, ему будут переданы только файлы `foo.c', `bar.c' и `baz.s'.
$(filter-out шаблон...,текст)
Удаляет из текста все разделенные пробелами слова, которые соответствуют какому-либо из перечисленных шаблонов, возвращая только слова, не соответствующие ни одному из шаблонов. Эта функция представляет собой "противоположность" функции filter. Если, например, у нас имеется такой фрагмент:
objects=main1.o foo.o main2.o bar.o
mains=main1.o main2.o
то следующее выражение возвратит список объектных файлов, не входящих в `mains':
$(filter-out $(mains),$(objects))
$(sort список)
Отсортировывает слова из списка в лексикографическом порядке, удаляя дубликаты (повторяющейся слова). Результатом является список слов, разделенных одиночными пробелами. Так, результатом выражения
$(sort foo bar lose)
будет строка `bar foo lose'. Даже если вас не интересует лексикографическая сортировка, вы можете пользоваться фунцией sort просто для удаления повторяющихся слов.
Вот довольно реалистичный пример использования функций subst и patsubst. Предположим, у вас имеется make-файл, в котором для указания списка каталогов, где make следует производить поиск пререквизитов, используется переменная VPATH (смотрите раздел Переменная VPATH: список каталогов для поиска пререквизитов). В следующем примере демонстрируется, как можно указать компилятору на необходимость поиска заголовочных файлов в том же списке каталогов.

Значение переменной VPATH представляет собой список имен каталогов, разделенных двоеточиями, например `src:../headers'. Сперва используем функцию subst для замены символов двоеточия на пробелы:

$(subst :, ,$(VPATH))
Полученный результат будет выглядеть как `src ../headers'. Далее, с помощью функции patsubst, преобразуем каждое из имен каталогов в соответствующую опцию `-I' компилятора. Полученное значение можно добавить к содержимому переменной CFLAGS, которая автоматически передается компилятору:

override CFLAGS += $(patsubst %,-I%,$(subst :, ,$(VPATH)))
Как результат, к первоначальному значению переменной CFLAGS добавляется строка `-Isrc -I../headers'. Директива override была использована для того, чтобы изменить значение переменной CFLAGS даже в том случае, если она была задана с помощью командной строки (смотрите раздел Директива override).

examp: 
bigoutput littleoutput : text.g
        generate text.g -$(subst output,,$@) > $@
эквивалентно
bigoutput : text.g
        generate text.g -big > bigoutput
littleoutput : text.g
        generate text.g -little > littleoutput